assume cs:code, ds:table, es:data

data segment
    ; 21个年份（每个4字节）
    db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
    db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
    db '1993','1994','1995'
    ; 21个总收入（每个双字4字节，起始偏移84）
    dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
    dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    ; 21个雇员数（每个字2字节，起始偏移168）
    dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
    dw 11542,14430,15257,17800
data ends

table segment
    ; 21个结构化条目，每个16字节(13-14)
    db 21 dup ('year summ ne ?? ')
table ends

stack segment
    db 16 dup(0)  ; 栈空间，用于保存循环计数
stack ends

code segment
start:
    ; 初始化段寄存器
    mov ax, data
    mov es, ax      ; ES指向data段（数据来源）
    mov ax, table
    mov ds, ax      ; DS指向table段（数据目标）
    mov ax, stack
    mov ss, ax
    mov sp, 16      ; 初始化栈顶

    mov cx, 21      ; 外层循环：处理21年数据
    mov bx, 0       ; BX：table段中当前条目的偏移（每次+16）

year_loop:
    push cx         ; 保存外层循环次数到栈

    ; ---------- 1. 计算当前年份索引 i = bx / 16 ----------
    mov ax, bx
    mov dx, 0
    mov cx, 16
    div cx          ; AX = i（年份索引），DX = 余数（无用）
    mov cx, 4       ; 恢复CX为内层循环次数（年份占4字节）

    ; ---------- 2. 复制年份到table（偏移0-3） ----------
    mov si, 0       ; SI：data中年份的起始偏移（i*4）
    mov di, 0       ; DI：table中年份的偏移（0-3）
year_copy:
    mov al, es:[si + ax*4 + di]
    mov ds:[bx + di], al
    inc di
    loop year_copy

    ; ---------- 3. 复制总收入到table（偏移5-8） ----------
    mov si, 84      ; SI：data中总收入的起始偏移（84）
    mov cx, 4       ; 内层循环次数（总收入占4字节）
    mov di, 5       ; DI：table中总收入的偏移（5-8）
income_copy:
    mov al, es:[si + ax*4 + di - 5]
    mov ds:[bx + di], al
    inc di
    loop income_copy

    ; ---------- 4. 复制雇员数到table（偏移10-11） ----------
    mov si, 168     ; SI：data中雇员数的起始偏移（168）
    mov cx, 2       ; 内层循环次数（雇员数占2字节）
    mov di, 10      ; DI：table中雇员数的偏移（10-11）
employee_copy:
    mov al, es:[si + ax*2 + di - 10]
    mov ds:[bx + di], al
    inc di
    loop employee_copy

    ; ---------- 5. 计算并存储人均收入（偏移13-14） ----------
    ; 读取总收入（双字，DX:AX）
    mov dx, es:[84 + ax*4 + 2]  ; 总收入高16位
    mov ax, es:[84 + ax*4]      ; 总收入低16位
    ; 读取雇员数（字，CX）
    mov cx, es:[168 + ax*2]
    ; 除法：总收入 ÷ 雇员数（结果AX为商，DX为余数）
    div cx
    ; 存储人均收入到table（偏移13-14）
    mov ds:[bx + 13], ax

    ; ---------- 准备下一次循环 ----------
    add bx, 16      ; 切换到table下一个条目
    pop cx          ; 恢复外层循环次数
    loop year_loop  ; CX--，若CX≠0则继续循环

    ; 程序结束
    mov ax, 4c00h
    int 21h

code ends
end start


/* 错误版本
assume cs:code
stack segment
	db 0,0,0,0,0,0,0,0
stack ends

data segment
	db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
	db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
	db '1993','1994','1995'
	;以上是表示21年的21个字符串
	
	dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
	dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
    ;以上是表示 21 年公司总收入的 21 个 dword 型数据
	
	dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
	dw 11542,14430,15257,17800
    ;以上是表示 21 年公司雇员人数的 21个 word 型数据
	
	dw 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21
	;以上是表示 21 年公司人均收入的 21个 word 型数据
data ends

table segment
	db 21 dup('year summ ne ?? ')
table ends


code segment
	start:
		mov ax,data
		mov es,ax	;指向data段
		mov bp,0	
		
		mov ax,table
		mov ds,ax	;指向table段
		mov bx,0	;定位每个结构性数据
		
		mov ax,stack
		mov ss,ax
		mov sp,8
		
		mov cx,21
		
	s:	push cx		;保存外层循环次数
		mov si,0	;定位数据项中的每个元素
		mov cx,2
	;一项数据的处理	
	;年份保存
	s0:
		mov ax,es:[bp].0[si]
		mov [bx][si],ax
		add si,2
		loop s0
		
		mov cx,2
		mov si,0
	;收入保存
	s1:
		mov ax,es:[bp].84[si]
		mov [bx].5[si],ax
		add si,2
		loop s1
	
		mov cx,1
		mov si,0
	;雇员数保存
		mov ax,es:[bp].168[si]
		mov [bx].10[si],ax
	;人均收入保存，为了简便，这里用1-21代替
		mov ax,es:[bp].210[si]
		mov [bx].13,ax
		
		pop cx
		add bx,16
		add bp,4
		
		loop s
		
code ends

end start
 */
 
